<template>
    <div class="file-upload">
        <el-row v-for="(item,index) in uploadFileList" :key="index">
            <el-col class="fileMain">
                <i class="el-icon-document"></i>
                <span>{{item.name}}</span>
                <el-link class="filePreview" v-show="showPreview" type="warning" @click="onPreview(item)">
                    {{$t('components.diskFileUpload.preview')}}
                </el-link>
                <el-link class="fileEditor" v-show="showEdit" type="primary" @click="onEdit(item,index)">
                    {{$t('components.diskFileUpload.edit')}}
                </el-link>
                <el-link class="fileDelete" type="danger" v-show="showDelete" @click="onRemove(item,index)">
                    {{$t('components.diskFileUpload.delete')}}
                </el-link>
            </el-col>
            <el-col class="fileDisable" v-if="!showEdit && !showPreview && !showDelete">
                <i class="el-icon-document-delete"></i>
                <span>{{item.name}}</span>
            </el-col>
        </el-row>
        <div class="fileAdd" @click="uploadFile" v-show="uploadFileList.length < maxLength">
            <i class="el-icon-plus"></i>
        </div>
         <el-upload
            class="upload"
            ref="upload"
            :headers="headers"
            :action="getAction()"
            :file-list="uploadFileList"
            :show-file-list="false"
            :http-request="customUploadFile">
            <el-button>{{$t('components.uploadfile.choose')}}</el-button>
        </el-upload>
        <!-- 自定义弹框 -->
        <div class="dialogDiv">
            <el-dialog
                    title="请选择模板"
                    center
                    width="20%"
                    top="30vh"
                    ref="dialog"
                    :modal="false"
                    :visible="showDialog"
                    :close-on-click-modal="true"
                    :show-close="true"
                    :before-close="dialogClose"
                    :modal-append-to-body="false">
            </el-dialog>
        </div>
    </div>
</template>

<script lang="ts">
import {Component, Vue, Prop, Inject} from 'vue-property-decorator';
import {Message, MessageBox} from 'element-ui';
import {Unsubscribable, Subject} from 'rxjs';
import { AppServiceBase, getSessionStorage } from '@ibizstudio/runtime';
import { getCookie } from 'qx-util';

@Component({})
export default class TextFileUpload extends Vue {

    /**
     * 视图上下文
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    @Prop() context!: any;

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    @Prop() viewparams!: any;

    /**
     * 视图参数
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    @Prop() filekey!: string;

    /**
     * 当前表单对象
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    @Prop() data!: any;

    /**
     * 当前属性名
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() formItemName!: string;

    /**
     * 当前属性值
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() value!: string;

     /**
     * 当前表单状态
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    @Inject('formState')
    formState!: Subject<any>

    /**
     * 默认为当前实体名称，有指定则按表单参数
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() folder!: string;

    /**
     * 默认为当前实体主键id，有指定则按表单参数
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() ownerid!: string;

    /**
     * 默认为当前属性名，有指定则按表单参数
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() ownertype!: string;

    /**
     * 持久化
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: false}) persistence?: boolean;

    /**
     * 是否显示拖拽区域
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: false}) showDrag?: boolean;

    /**
     * 是否显示预览按钮
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: true}) showPreview?: boolean;

    /**
     * 是否显示在线编辑按钮
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: true}) showEdit?: boolean;

    /**
     * 是否显示在线编辑按钮
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: 10}) maxLength?: number;

    /**
     * 是否显示在线删除按钮
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: true}) showDelete?: boolean;

    /**
     * 文件模板路径
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default:""})url?: string;

    /**
     * 是否显示OCR按钮
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    @Prop({default: false}) showOcrview?: boolean;

    /**
     * 查询参数
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() queryParam?: any;

    /**
     * 文件参数
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    @Prop() fileParam?: any;

    /**
     * 表单是否处于编辑状态（有真实主键,srfuf='1';srfuf='0'时处于新建未保存）
     *
     * @type {string}
     * @memberof DiskFileUpload
     */
    srfuf: string = '0';

    /**
     * 是否显示自定义弹框
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    showDialog: boolean = false;

    /**
     * 请求头
     * 
     * @type {*}
     * @memberof AppImageUpload 
     */
    headers: any = {};

    /**
     * 上传文件
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    uploadFile() {
      let queryParam: any = {};
      if(this.queryParam) {
        queryParam = this.$util.computedNavData(JSON.parse(this.data),this.context,this.viewparams,JSON.parse(this.queryParam));
      }
      if (this.url) {
        this.$http.get(this.url,queryParam).then((response: any) => {
            if (response && response.status !== 200) {
                return;
            }
            if (response.data.length > 0) {
              this.customUploadFile(response.data[0]);
            }else {
              this.customUploadFile({});
            }
        }).catch((response: any)=> {
          this.customUploadFile({});
        })
      }else {
          this.customUploadFile({});
      }
    }

    /**
     * 文件列表
     *
     * @type {Array<any>}
     * @memberof DiskFileUpload
     */
    uploadFileList: Array<any> = [];

    /**
     * 表单状态事件
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    formStateEvent: any | Unsubscribable | undefined;

    /**
     * 批量更新标识，false为不更新，true才可以更新
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    isUpdateBatch: boolean = true;

    /**
     * 新建状态标识,true为新建，false为编辑
     *
     * @type {boolean}
     * @memberof DiskFileUpload
     */
    isCreate: boolean = true;

    /**
     * 自定义弹框标题
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    dialogTitle: any = '';

    /**
     * 嵌入自定义弹框中iframe的url
     *
     * @type {*}
     * @memberof DiskFileUpload
     */
    iframeUrl: any = '';

    /**
     * 文件状态：init初始化、upload新建、save保存
     * @type {string}
     * @memberof DiskFileUpload
     */
    textstate: string = 'init';

    /**
     * 编辑文件
     *
     * @memberof DiskFileUpload
     */
    editorFile() {
        let url: string = '';
        window.open(url);
    }

    /**
     * 关闭自定义弹框
     *
     * @memberof DiskFileUpload
     */
    dialogClose() {
        this.dialogTitle = '';
        this.showDialog = false;
        // this.iframeUrl = '';
        // let iframe: any = document.getElementById("fileIframe");
        // iframe.parentNode.removeChild("fileIframe");
    }

    /**
     * 拼接上传路径
     *
     * @memberof DiskFileUpload
     */
    getAction() {
        return '/net-disk/upload/' + this.getFolder() + '?ownertype=' + this.getOwnertype() + '&ownerid=' + this.getOwnerid();
    }

    /**
     * return folder
     *
     * @memberof DiskFileUpload
     */
    getFolder() {
        return typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder);
    }

    /**
     * return ownertype
     *
     * @memberof DiskFileUpload
     */
    getOwnertype() {
        return typeof this.ownertype == "string" ? this.ownertype : JSON.stringify(this.ownertype);
    }

    /**
     * return ownerid
     *
     * @memberof DiskFileUpload
     */
    getOwnerid($event?: any) {
        if ($event && $event[this.filekey]) {
            return typeof $event[this.filekey] == "string" ? $event[this.filekey] : JSON.stringify($event[this.filekey]);
        }
        return typeof this.ownerid == "string" ? this.ownerid : JSON.stringify(this.ownerid);
    }

    /**
     * vue创建
     *
     * @memberof DiskFileUpload
     */
    created() {
        this.setHeaders();
        this.formStateEvent = this.formState.subscribe(($event: any) => {
            // 表单加载完成
            if (Object.is($event.type, 'load')) {
                const data = JSON.parse(JSON.stringify($event.data));
                // 编辑表单，保存时不进行批量更新
                if (data.srfuf == '1') {
                    this.isCreate = false;
                    this.isUpdateBatch = false;
                }
                // 当persistence = true时
                
                if (this.persistence == true) {
                    // 直接从表单的data数据里获取当前属性的值
                    if (data[this.formItemName] && this.uploadFileList.length == 0) {
                        const files = JSON.parse(data[this.formItemName]);
                        for (let i = 0; i < files.length; i++) {
                            this.uploadFileList.push(files[i]);
                        }
                    }
                } else {
                    // 发送get请求获取文件列表
                    this.getFiles();
                }
            }
            // 表单保存完成
            if (Object.is($event.type, 'save')) {
                // 批量更新文件表中的ownerid
                if (this.isUpdateBatch == true && this.uploadFileList.length > 0) {
                    this.updateFileBatch(this.uploadFileList,$event);
                }
            }
        });
    }

    destroyed() {
      if (this.formStateEvent) {
        this.formStateEvent.unsubscribe();
      }
    }
    
    /**
     * 设置请求头
     * 
     * @memberof AppFileUpload
     */
    setHeaders(){
        if (AppServiceBase.getInstance().getAppEnvironment().SaaSMode) {
            let activeOrgData = getSessionStorage('activeOrgData');
            this.headers['srforgid'] = activeOrgData?.orgid;
            this.headers['srfsystemid'] = activeOrgData?.systemid;
            if(getSessionStorage("srfdynaorgid")){
                this.headers['srfdynaorgid'] = getSessionStorage("srfdynaorgid");
            }
        } else {
            this.headers['srforgid'] = undefined;
            this.headers['srfsystemid'] = undefined;
            if(getSessionStorage("srfdynaorgid")){
                this.headers['srfdynaorgid'] = getSessionStorage("srfdynaorgid");
            }
        }
        if (getCookie('ibzuaa-token')) {
            this.headers['Authorization'] = `Bearer ${getCookie('ibzuaa-token')}`;
        } else {
            // 第三方应用打开免登
            if (sessionStorage.getItem("srftoken")) {
                const token = sessionStorage.getItem('srftoken');
                this.headers['Authorization'] = `Bearer ${token}`;
            }
        }
    }

    /**
     * 获取文件列表
     *
     * @memberof DiskFileUpload
     */
    getFiles() {
        // 拼接url
        let _this: any = this;
        const getUrl = '/net-disk/files/' + this.getFolder();
        // 发送get请求
        this.$http.get(getUrl, {
                ownertype: this.getOwnertype(),
                ownerid: this.getOwnerid(),
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.getFileFailure') + "!",'getFiles');
                return;
            }
            // 返回的是一个jsonArray
            if (response.data.length > 0) {
                const files = JSON.parse(JSON.stringify(response.data));
                if (this.uploadFileList.length == 0) {
                    this.uploadFileList.push.apply(this.uploadFileList, files);
                }
            }
        }).catch((error: any) => {
            this.$throw(error,'getFiles');
        });
    }

    /**
     * 自定义上传文件
     *
     * @param 上传文件
     * @memberof DiskFileUpload
     */
    async customUploadFile(param: any) {
        let fileParam: any = {};
        if(this.fileParam) {
          fileParam = this.$util.computedNavData(JSON.parse(this.data),this.context,this.viewparams,JSON.parse(this.fileParam));
        }
        //文件名与文件类型
        let fileName = "模板文件";
        let filetype = ".wps"
        let filemime = "application/kswps";
        let fileText = "";
        //文件数据
        let tempfile: any = {};
        // 上传的文件
        let _this: any = this;
        if (param[fileParam.id]) {
          const getUrl = '/net-disk/files/' + this.getFolder();
          // 发送get请求
          await this.$http.get(getUrl, {
              ownertype: this.getOwnertype(),
              ownerid: param[fileParam.id]
          }).then((response: any) => {
              if (!response || response.status != 200) {
                  this.$throw(_this.$t('components.diskimageupload.getFileFailure') + "!",'customUploadFile');
                  return;
              }
              // 返回的是一个jsonArray
              if (response.data?.length > 0) {
                  tempfile = response.data[0];
                  fileName = response.data[0]?.filename.split(".")[0];
                  filetype = response.data[0]?.ext;
                  filemime = this.calcFilemime(response.data[0]?.ext);
              }
          }).catch((error: any) => {
              this.$throw(error,'customUploadFile');
          });
        }
        //获取文件内容
        if (Object.keys(tempfile).length > 0) {
          const id = typeof tempfile.id == "string" ? tempfile.id : JSON.stringify(tempfile.id);
          const name = typeof tempfile.name == "string" ? tempfile.name : JSON.stringify(tempfile.filename);
          const downloadUrl = '/net-disk/download/' + this.getFolder() + '/' + id + '/' + name;
          // 发送get请求
          await this.$http.get(downloadUrl, {
              'authcode': tempfile.authcode,
              responseType: 'arraybuffer',
          }).then((response: any) => {
              if (!response || response.status != 200) {
                  this.$throw(_this.$t('components.diskimageupload.downloadFile') + "!",'customUploadFile');
                  return;
              }
              // 请求成功，后台返回的是一个文件流
              if (response.data) {
                  fileText = response.data;
              } else {
                  this.$throw(_this.$t('components.diskimageupload.downloadFile1') + "!",'customUploadFile');
              }
          }).catch((error: any) => {
              this.$throw(error,'customUploadFile');
          });
        }
        //配置优先级最高
        fileName = fileParam.filename?fileParam.filename:fileName;
        filetype = fileParam.filetype?fileParam.filetype:filetype;
        filemime = fileParam.filetype?this.calcFilemime(fileParam.filetype):fileParam.filetype;
        let file = new File([fileText],fileName + filetype,{type: filemime});
        if (this.textstate === "init") {
            this.textstate = "upload";
        }
        // formData传参
        let formData = new FormData();
        formData.append('file', file);
        // 拼接url
        const uploadUrl = this.getAction();
        // 发送post请求
        this.$http.post(uploadUrl, formData, {timeout: 2000}).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.loadFailure') + "!",'customUploadFile');
            }
            // 返回的是一个jsonobject
            if (response.data) {
                // 新建表单上传，后续需要批量更新操作
                if (this.isCreate == true) {
                    this.isUpdateBatch = true;
                }
                Object.assign(response.data,{file})
                // 保存到文件列表进行显示
                this.uploadFileList.push(response.data);
                // persistence=true时需要持久化表单属性
                if (this.persistence == true && this.uploadFileList.length > 0) {
                    const value = JSON.stringify(this.uploadFileList);
                    this.$emit('formitemvaluechange', {name: this.formItemName, value: value});
                }
            }
        }).catch((error: any) => {
            this.$throw(error,'customUploadFile');
        })
    }

    /**
     * 计算文件mime类型
     *
     * @param filetype 文件后缀
     * @memberof DiskFileUpload
     */
    calcFilemime(filetype: string): string {
      let mime = "application/kswps";
      switch(filetype) {
        case ".wps":
          mime = "application/kswps";
          break;
        case ".doc":
          mime = "application/msword";
          break;
        case ".docx":
          mime = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
          break;
        case ".txt":
          mime = "text/plain";
          break;
      }
      return mime;
    }

    /**
     * 下载文件
     *
     * @param item 下载文件
     * @memberof DiskFileUpload
     */
    onDownload(item: any) {
        // 拼接url
        let _this: any = this;
        const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
        const name = typeof item.name == "string" ? item.name : JSON.stringify(item.filename);
        const downloadUrl = '/net-disk/download/' + this.getFolder() + '/' + id + '/' + name;
        // 发送get请求
        this.$http.get(downloadUrl, {
            'authcode': item.authcode,
            responseType: 'arraybuffer',
        }).then((response: any) => {
            if (!response || response.status != 200) {
                this.$throw(_this.$t('components.diskimageupload.downloadFile1') + "!",'onDownload');
                return;
            }
            // 请求成功，后台返回的是一个文件流
            if (response.data) {
                // 获取文件名
                const disposition = response.headers['content-disposition'];
                const filename = disposition.split('filename=')[1];
                // 用blob对象获取文件流
                let blob = new Blob([response.data], {type: response.headers['content-type']});
                // 通过文件流创建下载链接
                var href = URL.createObjectURL(blob);
                // 创建一个a元素并设置相关属性
                let a = document.createElement('a');
                a.href = href;
                if (name) {
                    a.download = name;
                } else {
                    a.download = filename;
                }
                // 添加a元素到当前网页
                document.body.appendChild(a);
                // 触发a元素的点击事件，实现下载
                a.click();
                // 从当前网页移除a元素
                document.body.removeChild(a);
                // 释放blob对象
                URL.revokeObjectURL(href);
            } else {
                this.$throw(_this.$t('components.diskimageupload.downloadFile1') + "!",'onDownload');
            }
        }).catch((error: any) => {
            this.$throw(error,'onDownload');
        });
    }

    /**
     * 预览文件
     *
     * @param item 预览文件
     * @memberof DiskFileUpload
     */
    onPreview(item: any) {
        // 拼接url
        const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
        const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
        let previewUrl = '/net-disk/preview/' + this.getFolder() + '/' + id + '/' + name + '?authcode=' + item.authcode;
        this.$http.get(previewUrl).then((response: any) => {
            if (!response || response.status != 200) {
                return;
            }
            if (response.data) {
                window.open(response.data);
            }
        }).catch((error: any) => {
            this.$throw(error,'onPreview');
        });
    }

    /**
     * 编辑文件
     *
     * @param item
     * @memberof DiskFileUpload
     */
    onEdit(item: any, index: number) {
        // 拼接url
        const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
        const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
        const editUrl = '/net-disk/editview/' + this.getFolder() + '/' + id + '/' + name + '?authcode=' + item.authcode;
        this.$http.get(editUrl).then((response: any) => {
            if (!response || response.status != 200) {
                return;
            }
            if (response.data) {
                window.open(response.data);
            }
        }).catch((error: any) => {
            this.$throw(error,'onEdit');
        });
    }

    /**
     * ocr识别
     * @param item
     * @memberof DiskFileUpload
     */
    onOcr(item: any) {
        // 拼接url
        const folder = typeof this.folder == "string" ? this.folder : JSON.stringify(this.folder);
        const id = typeof item.id == "string" ? item.id : JSON.stringify(item.id);
        const name = typeof item.name == "string" ? item.name : JSON.stringify(item.name);
        const ocrUrl = '/net-disk/ocrview/' + this.getFolder() + '/' + id + '/' + name + '?authcode=' + item.authcode;
        this.$http.get(ocrUrl).then((response: any) => {
            if (!response || response.status != 200) {
                return;
            }
            // 返回一个url，通过自定义弹框打开
            if (response.data) {
                this.dialogTitle = name;
                this.showDialog = true;
                this.iframeUrl = response.data;
            }
        }).catch((error: any) => {
            this.$throw(error,'onOcr');
        });
    }

    /**
     * 删除文件
     *
     * @param item
     * @param index
     * @memberof DiskFileUpload
     */
    onRemove(item: any, index: number) {
        let _this: any = this;
        if (item) {
            MessageBox.confirm(_this.$t('components.diskFileUpload.deleteFile'), _this.$t('components.diskFileUpload.deleteFilePrompt'), {
                confirmButtonText: _this.$t('components.diskFileUpload.true'),
                cancelButtonText: _this.$t('components.diskFileUpload.false'),
                type: 'warning'
            }).then(() => {
                //　拼接url
                const deleteUrl = '/net-disk/files/' + item.id;
                // 发送delete请求
                this.$http.delete(deleteUrl).then((response: any) => {
                    if (!response || response.status != 200) {
                        this.$throw(_this.$t('components.diskimageupload.deletefileFailure') + "!",'onRemove');
                        return
                    }
                    // 从文件列表中删除
                    this.uploadFileList.splice(index, 1);
                    // persistence=true时需要持久化表单属性
                    if (this.persistence == true) {
                        const value = JSON.stringify(this.uploadFileList);
                        this.$emit('formitemvaluechange', {name: this.formItemName, value: value});
                    }
                }).catch((error: any) => {
                    // 提示删除失败
                    this.$throw(error,'onRemove');
                });
            });
        }
    }

    /**
     * 批量更新文件表的ownerid
     *
     * @memberof DiskFileUpload
     */
    updateFileBatch(files: any,$event: any) {
        if (this.textstate !== "upload") {
          return;
        }
        this.textstate = "save";
        let _this: any = this;
        // 拼接url
        const updateUrl = '/net-disk/upload/' + this.getFolder() + '?ownertype=' + this.getOwnertype() + "&ownerid=" + this.getOwnerid($event.data);
        // requestBody参数
        if (files.length > 0) {
            files.forEach((item: any) => {
              if (item.file) {
                const deleteUrl = '/net-disk/files/' + item.id;
                // 发送delete请求
                this.$http.delete(deleteUrl).then((response: any) => {
                    if (!response || response.status != 200) {
                        this.$throw(_this.$t('components.diskimageupload.deletefileFailure') + "!",'updateFileBatch');
                    }
                }).catch((error: any) => {
                    // 提示删除失败
                    this.$throw(error,'updateFileBatch');
                });
                let formData = new FormData();
                formData.append('file', item.file);
                // 发送post请求
                this.$http.post(updateUrl, formData, {timeout: 2000}).then((response: any) => {
                    if (!response || response.status != 200) {
                        this.$throw(_this.$t('components.diskimageupload.loadFailure') + "!",'updateFileBatch');
                        return;
                    }
                    item.fileid = response.data.fileid;
                    item.id = response.data.id;
                    item.authcode = response.data.authcode;
                }).catch((error: any) => {
                    this.$throw(error,'updateFileBatch');
                });
              }
            });
        }
    }
}
</script>
<style lang="less">
@import './text-file-upload.less';
</style>